package com.kj.report.service.impl;

import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.jayway.jsonpath.JsonPath;
import com.kj.common.exception.RestException;

import com.kj.common.response.Response;
import com.kj.member.interfaces.CustomerInfoRMI;
import com.kj.member.model.Customer;
import com.kj.report.mapper.DeviceMapper;
import com.kj.report.mapper.DeviceUserRelationMapper;
import com.kj.report.model.*;
import com.kj.report.mongoRepository.ReportBaseThreeDataRepository;

import com.kj.report.service.InspectResultBaseInfoService;
import com.kj.report.service.ReportV3Service;
import com.kj.report.utils.Basedata;
import com.kj.report.utils.DataTransitionUtil;
import com.kj.report.utils.RedisUtils;
import com.kj.report.utils.ReportBaseUtil;
import com.kj.report.utils.enumUtil.ReportCode;
import net.minidev.json.JSONArray;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;

@Service
public class ReportV3ServiceImpl implements ReportV3Service {

    @Resource
    private ReportBaseThreeDataRepository reportRepository;
    @Resource
    private RedisUtils redisUtils;
    @Resource
    private CustomerInfoRMI customerInfoRMI;
    @Resource
    private DeviceMapper deviceMapper;
    @Resource
    private DeviceUserRelationMapper deviceUserRelationMapper;
    @Resource
    private HealthAdviceServiceImpl healthAdviceService;
    @Resource
    private InspectResultBaseInfoService inspectResultBaseInfoService;

    @Value("${robot.baseUrl}")
    private String url;
    @Value("${agent.kjAgentId}")
    private String agentId;
    @Value("${agent.kjAgentKey}")
    private String agentKey;
    @Value("${recipes.url}")
    private String recipesUrl;

    /**报告3.0生成
     * @auther: Tony
     * @date: 2018/10/30 11:44
     * @param: [reportId]
     * @return: com.kj.common.response.Response<?>
     */
    @Override
    public Response<String> reportGeneration(String reportId, Long userId) {
        //检查报告是否存在
        ReportBaseThreeData report = this.reportRepository.findById(reportId);
        if (report != null){
            return new Response().success("报告已存在");
        }
        //获取用户信息customer
        Customer userInfo =customerInfoRMI.queryCustomerById(userId).getResult();
        // = customerResult.getResult();
        if (userInfo == null){
            throw new RestException(ReportCode.report_405.getCode(),"没有用户信息需要创建");
        }
        //判断手机号
        if (userInfo.getMobile()==null||"".equals(userInfo.getMobile())){
            throw new RestException(ReportCode.report_402.getCode(),"需要完善用户信息");
        }
        //判断用户年龄
        if (userInfo.getAge()==null||userInfo.getAge()==0){
            throw new RestException(ReportCode.report_403.getCode(),"没有用户年龄");
        };
        //获取token
        String token = ReportBaseUtil.getTokenKey(redisUtils,url,agentId,agentKey);
        // 初始化基础数据
        String reportBaseData= Basedata.basedata;
        //获取报告基础数据
        String reportData = ReportBaseUtil.getReportData(url,reportId, userInfo.getAge(), String.valueOf(userInfo.getCustomerId()),token);
        if(StringUtils.isEmpty(reportData)){
            //没有基础数据
            throw new RestException(ReportCode.report_401.getCode(),"没有基础数据");
        }
        Integer read = JsonPath.read(reportData, "$.code");
        if (read != 0){
            //没有原始数据
            throw new RestException(ReportCode.report_400.getCode(),"没有原始数据");
        }
        // 获取设备信息
        Device device = new Device();
        device.setSnNum(JsonPath.read(reportData,"$.data.robotSn"));//设备sn
        Device deviceInfo = this.deviceMapper.selectDeviceObjSingle(device);
        if (deviceInfo == null){
            throw new RestException(ReportCode.report_1101.getCode(),"没有此设备信息："+device.getSnNum());
        }
        //获取膳食建议
        String newPropose = ReportBaseUtil.getNewPropose(redisUtils, url, token);
        //获取报告第三层数据
        JSONArray jsonArray  = JsonPath.read(reportData, "$..threeTarget");
        //身体状况数据
        List<Map<String,Object>> pstarget= JsonPath.read(reportData,"$.data.psTargets");

        Map<String,Map<String,Object>> reportMap = Maps.newHashMap();
        for (int i=0;i<jsonArray.size();i++){
            JSONArray threeArray = (JSONArray) jsonArray.get(i);
            for (int j = 0; j < threeArray.size(); j++) {
                Map<String, Object> maps = (Map<String, Object>) threeArray.get(j);
                Map<String,Object> scoreMap = new HashMap<String, Object>();
                scoreMap.put("index","target");
                scoreMap.put("abLevel",maps.get("abLevel"));
                scoreMap.put("offset",maps.get("offset"));
                scoreMap.put("score",maps.get("score"));
                reportMap.put(String.valueOf(maps.get("targetId")),scoreMap);
            }
        }

        //遍历身体状况数据
        for (int i = 0; i <pstarget.size() ; i++) {
            Map<String, Object> maps = pstarget.get(i);
            Map<String,Object> scoreMap = new HashMap<String, Object>();
            scoreMap.put("index","pstarget");
            scoreMap.put("abLive",maps.get("abLive"));
            reportMap.put(String.valueOf(maps.get("targetId")),scoreMap);
        }
        //基础数据
        List<HashMap<String,Object>> basedata=JsonPath.read(reportBaseData,"$");
        //拼接食谱参数
        List<Map<String,String>>  recipesList = Lists.newArrayList();
        //报告数据
        List<ReportNewThreeViem> reportViem = new ArrayList<ReportNewThreeViem>();
        for (int i = 0; i <basedata.size() ; i++) {
            HashMap<String, Object> reportprentMap = basedata.get(i);
            //报告格式实例
            ReportNewThreeViem reportmodel = new ReportNewThreeViem();
            List<ReportNewThreeViemChild> childList = new ArrayList<ReportNewThreeViemChild>();
            List<HashMap<String,Object>> childMenus = (List<HashMap<String,Object>>)basedata.get(i).get("childMenus");
            reportmodel.setParentId(0);//父节点Id
            reportmodel.setTargetId(DataTransitionUtil.objToInteger(reportprentMap.get("id"))); //指标Id
            reportmodel.setTargetName(DataTransitionUtil.objToString(reportprentMap.get("name")));//指标名称
            reportmodel.setExplain(String.valueOf(reportprentMap.get("explain")));
            if("1004".equals(reportprentMap.get("id"))){
                //获取BMI值
                double bmiValue = ReportBaseUtil.getBmiValue(userInfo);
                reportmodel.setScore(bmiValue);
            }
            for (int j = 0; j <childMenus.size() ; j++) {
                HashMap<String, Object> child = childMenus.get(j);
                //通过基础数据Id获取数据
                Map<String,Object> targetObj = reportMap.get(String.valueOf(child.get("id")));
                if (targetObj != null){
                    //报告二级实例
                    ReportNewThreeViemChild reportchild = new ReportNewThreeViemChild();
                    //指标Id
                    reportchild.setTargetId(DataTransitionUtil.objToInteger(child.get("id")));
                    reportchild.setTargetName(DataTransitionUtil.objToString(child.get("name")));//指标名称
                    reportchild.setExplain(String.valueOf(child.get("explain")));
                    //父节点Id
                    reportchild.setParentId(DataTransitionUtil.objToInteger(basedata.get(i).get("id")));
                    reportchild.setScore(DataTransitionUtil.objToInteger(targetObj.get("score")));//分数
                    reportchild.setOffset(DataTransitionUtil.objToInteger(targetObj.get("offset")));//指标偏移量
                    reportchild.setAbLevel(DataTransitionUtil.objToInteger(targetObj.get("abLevel")));//指标异常程度
                    reportchild.setAbLive(String.valueOf(targetObj.get("abLive")));//身体状况
                    //拼接食谱参数
                    Map<String,String> recipesParam = Maps.newHashMap();
                    if (targetObj.get("index").equals("target")){
                        recipesParam.put("targetId",reportchild.getTargetId()+"");
                        recipesParam.put("score",String.valueOf(reportchild.getScore()));
                        recipesParam.put("abnormalLevel",reportchild.getAbLevel()==null?"1":String.valueOf(reportchild.getAbLevel()));
                        recipesParam.put("inspectStandard",reportchild.getOffset()==null?"1":String.valueOf(reportchild.getOffset()));
                        recipesList.add(recipesParam);
                    }
//拼接建议
                    HealthAdviceView healthAdviceView = null;

                    if(targetObj.get("offset")!=null&& targetObj.get("abLevel")!=null && DataTransitionUtil.objToInteger(targetObj.get("abLevel")) > 1 && DataTransitionUtil.objToInteger(targetObj.get("offset")) > 1){
                        healthAdviceView =   new HealthAdviceView();
                        List<TsIndexTypeView> dietList = Lists.newArrayList();// 膳食建议
                        List<TsIndexTypeView> nutritionList = Lists.newArrayList();// 营养建议
                        List<TsIndexTypeView> motionList = Lists.newArrayList();// 运动和生活方式建议
                        List<Map<String, Object>> propose = JsonPath.read(newPropose, "$.relation");
                        propose.stream().filter(proposeParam
                                -> {
                            return proposeParam.get("targetId") != null && (proposeParam.get("targetId").toString().equals(String.valueOf(reportchild.getTargetId())) &&
                                    String.valueOf(proposeParam.get("offset")).equals(String.valueOf(reportchild.getOffset())));
                        }).forEach(proposeParam -> { //1 是营养建议  2 膳食建议  3 运动建议/* 1 、膳食建议 2、营养 3、运动 */
                            //获取建议
                            List<Map<String, Object>> indexTypeIds = JsonPath.read(proposeParam.get("indexTypeIds"), "$");
                            indexTypeIds.stream().forEach(indexTypeIdsparam -> {
                                TsIndexTypeView tsIndexTypeView = new TsIndexTypeView();
                                tsIndexTypeView.setIndexTypeId(DataTransitionUtil.objToString(indexTypeIdsparam.get("indexTypeId")));
                                tsIndexTypeView.setSimpleDescription(DataTransitionUtil.objToString(indexTypeIdsparam.get("simpleDescription")));//建议描述
                                if (indexTypeIdsparam.get("personality")!=null&&indexTypeIdsparam.get("expression") != null){
                                    String personality = healthAdviceService.scriptEngine(0,reportchild.getAbLevel() ,
                                            indexTypeIdsparam.get("expression").toString(), indexTypeIdsparam.get("personality").toString());
                                    tsIndexTypeView.setPersonality(personality);//  /* 膳食建议 */
                                }

                                tsIndexTypeView.setProposal(DataTransitionUtil.objToString(indexTypeIdsparam.get("proposal")));// /* 营养建议 */

                                tsIndexTypeView.setIndexName(DataTransitionUtil.objToString(indexTypeIdsparam.get("indexName")));//指标名称
                                tsIndexTypeView.setIndexCode(DataTransitionUtil.objToString(indexTypeIdsparam.get("indexCode")));//指标code
                                //tsIndexTypeView.setProposal(indexTypeIdsparam.get("proposal").toString());// /* 膳食建议 */
                                if ("1".equals(String.valueOf(indexTypeIdsparam.get("indexType")))) {
                                    nutritionList.add(tsIndexTypeView);
                                } else if ("2".equals(String.valueOf(indexTypeIdsparam.get("indexType")))) {
                                    dietList.add(tsIndexTypeView);
                                } else if ("3".equals(String.valueOf(indexTypeIdsparam.get("indexType")))) {
                                    motionList.add(tsIndexTypeView);
                                }
                            });
                        });
                        healthAdviceView.setDietList(dietList);
                        healthAdviceView.setMotionList(motionList);
                        healthAdviceView.setNutritionList(nutritionList);

                    }
                    reportchild.setHealthAdviceVo(healthAdviceView);
                    childList.add(reportchild);
                }
            }
            //放入子集结果
            reportmodel.setChildTarget(childList);
            reportmodel.setHintName(DataTransitionUtil.objToInteger(reportprentMap.get("id")),null);

            reportViem.add(reportmodel);
        }
        String recipes = ReportBaseUtil.getRecipes(recipesUrl, recipesList, reportId);
        ReportBaseThreeData reportBaseThreeData = new ReportBaseThreeData();
        reportBaseThreeData.setReportId(reportId);
        reportBaseThreeData.setRecipesStr(recipes);
        reportBaseThreeData.setUserId(String.valueOf(userId));
        reportBaseThreeData.setHeight(userInfo.getHeight());
        reportBaseThreeData.setWeight(userInfo.getWeight());
        reportBaseThreeData.setReportNewThreeViems(reportViem);
        Integer sex = JsonPath.read(reportData, "$.data.gender");
        Integer score = JsonPath.read(reportData, "$.data.totalScore");
        reportBaseThreeData.setSex(sex);
        reportBaseThreeData.setTotalScore(score);
        reportBaseThreeData.setHeadimgurl(userInfo.getHeadimgurl());


        Integer totalScore = reportBaseThreeData.getTotalScore();
        Map<String, Object> supplementMap = supplementThreeReportdata(userInfo, deviceInfo, reportData, totalScore);
        reportBaseThreeData.setInspectDate((Date) supplementMap.get("inspectDate"));      //当前系统时间
        reportBaseThreeData.setInspectDateStr(DataTransitionUtil.objToString(supplementMap.get("inspectDateStr")));
        reportBaseThreeData.setAge(DataTransitionUtil.objToInteger(supplementMap.get("age")));
        reportBaseThreeData.setIsCharge(DataTransitionUtil.objToInteger(supplementMap.get("isCharge")));
        reportBaseThreeData.setReportType(DataTransitionUtil.objToInteger(supplementMap.get("reportType")));
        reportBaseThreeData.setDeviceType(DataTransitionUtil.objToInteger(supplementMap.get("deviceType")));
        reportBaseThreeData.setTitleSex(DataTransitionUtil.objToString(supplementMap.get("titleSex")));
        reportBaseThreeData.setDeviceSnNum(DataTransitionUtil.objToString(supplementMap.get("deviceSnNum")));
        reportBaseThreeData.setDeviceMacAddress(DataTransitionUtil.objToString(supplementMap.get("deviceMacAddress")));
        reportBaseThreeData.setDeviceId(DataTransitionUtil.objToLong(supplementMap.get("deviceId")));
        reportBaseThreeData.setSceneId(DataTransitionUtil.objToInteger(supplementMap.get("sceneId")));
        reportBaseThreeData.setSceneSecondId(DataTransitionUtil.objToString(supplementMap.get("sceneSecondId")));
        reportBaseThreeData.setAgentId(DataTransitionUtil.objToString(supplementMap.get("agentId")));
        reportBaseThreeData.setAgentIds(DataTransitionUtil.objToString(supplementMap.get("agentIds")));
        reportBaseThreeData.setRanking(DataTransitionUtil.objToInteger(supplementMap.get("ranking")));
//        reportBaseThreeDataDao.insert(reportBaseThreeData);
//        logger.info("reportId :"+reportId+"---插入mongo完成"+"---userId："+userId);
//        insertinspectresultbaseinfo(reportBaseThreeData,userInfo);
//        logger.info("reportId :"+reportId+"---插入insertinspectresultbaseinfo完成"+"---userId："+userId);
//        insertThirdView(reportBaseThreeData,userInfo,deviceInfo);
//        logger.info("reportId :"+reportId+"---插入inspectDds3Score完成"+"---userId："+userId);
//        addInspectDdsScore(reportBaseThreeData);
//        logger.info("reportId ："+reportId+"---插入inspectDdsScore完成"+"---userId："+userId);

          return null;
    }

    public Map<String,Map<String,Object>> reportJsonarrToMap(JSONArray jsonArray,Map<String,Map<String,Object>> resultMap){
        jsonArray.stream().forEach(param ->{
                System.out.println(param);
        });

        return resultMap;
    }

    private Map<String,Object> supplementThreeReportdata(Customer userInfo, Device deviceInfo, String reportData, Integer totalScore){
        Map<String,Object> threeReportMap = Maps.newHashMap();
        Date date = new Date();
        threeReportMap.put("inspectDate",date);                                          //报告时间
        String inspectDateStr = ReportBaseUtil.getTimestampStr(date);
        threeReportMap.put("inspectDateStr",inspectDateStr);
        threeReportMap.put("isCharge",DataTransitionUtil.objToInteger(deviceInfo.getDeviceTypeId()));//是否收费
        threeReportMap.put("reportType",deviceInfo.getDeviceReport());                         //报告类型
        threeReportMap.put("deviceType",deviceInfo.getDeviceType());                           //设备类型
        Integer gender = userInfo.getSex();
        threeReportMap.put("titleSex","亲爱的"+userInfo.getNickName()+(gender == 1?"先生":"女士"));//用户性别
        threeReportMap.put("deviceSnNum",deviceInfo.getSnNum());                               //设备sn码
        threeReportMap.put("deviceMacAddress",deviceInfo.getMacAddress());                     //设备地址
        threeReportMap.put("deviceId",deviceInfo.getDeviceId());                                //设备Id
        threeReportMap.put("sceneId",deviceInfo.getSceneId());                                  //场景Id
        threeReportMap.put("sceneSecondId",deviceInfo.getSceneSecondId());                     //小场景Id
        threeReportMap.put("age",JsonPath.read(reportData,"$.data.inspectAge"));    //报告年龄

        String agentIds = "1";
        String provinceIds = ",";
        String cityIds = "";

        DeviceUserRelation deviceUserRelation = new DeviceUserRelation();
        deviceUserRelation.setDeviceId(DataTransitionUtil.longToInteger(deviceInfo.getDeviceId()));

        List<DeviceUserRelation> durs = deviceUserRelationMapper.selectList(deviceUserRelation);
        if (durs != null && durs.size() > 0) {
            for (DeviceUserRelation dur : durs) {
                if (dur.getIsBuyers() == 1) {
                    threeReportMap.put("agentId",(dur.getUserId()+""));                         //代理人Id
                    provinceIds += dur.getUserId();
                }else if (dur.getIsBuyers() == 2) {
                    cityIds += ","+dur.getUserId();
                }
            }
        }

        threeReportMap.put("agentIds",(agentIds+provinceIds+cityIds));                          //代理商关系Id
        //分数排名
        Integer age = (Integer) threeReportMap.get("age");
        //不做版本排名
        Integer ranking = inspectResultBaseInfoService.rankingUserScore(totalScore,5,age);
        threeReportMap.put("ranking",ranking);
        return threeReportMap;
    }
}
